package cn.trs.common.utils;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @version 1.0
 * @author:TRS
 * @create:2023/2/23 10:11
 * @description:
 * @ClassName: FileUtil
 * @company TRS
 */
public class FileUtil {

    public static void uploadFile(MultipartFile file, String originalFilename) throws Exception {
        makeDir(originalFilename.substring(0, originalFilename.lastIndexOf("/")));
        File newFile = new File(originalFilename);
        file.transferTo(newFile);
    }

    /**
     * 递归删除目录下的文件包含删除该目录(为了防止误删除，必须指定根目录名字的规则)
     *
     * @param path
     * @param contain 目录必须包含的字符串，不能为空，且长度必须大于10
     */
    public static void deleteTempDirFiles(String path, String contain) {
        if (!StringUtils.isBlank(path) && !StringUtils.isBlank(contain) && contain.length() > 10) {
            if (path.replace("/", "").replace("\\", "").contains(contain.replace("/", "").replace("\\", ""))) {
                File file = new File(path);
                if (file.exists()) {
                    if (file.isDirectory()) {
                        //是文件夹
                        File[] files = file.listFiles();
                        if (files != null && files.length > 0) {
                            for (int i = 0; i < files.length; i++) {
                                deleteTempDirFiles(files[i].getAbsolutePath(), contain);
                            }
                        }
                        //删除空文件夹
                        file.delete();
                    } else {
                        //是文件
                        file.delete();
                    }
                }
            }
        }
    }

    /**
     * 删除单个文件
     *
     * @param path
     */
    public static void deleteOneFile(String path) {
        if (!StringUtils.isBlank(path)) {
            File file = new File(path);
            if (file.exists() && file.isFile()) {
                file.delete();
            }
        }
    }

    /**
     * 创建文件夹
     *
     * @param path
     * @return
     */
    public static File makeDir(String path) {
        File fileDir = new File(path);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        return fileDir;
    }

    /**
     * 从网络Url中下载文件
     *
     * @param urlStr
     * @param fileName
     * @param savePath
     * @throws IOException
     */
    public static void downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException {
        System.out.println("===============================start_download:" + urlStr + ",time:" + System.currentTimeMillis());
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(60000);//读取数据超时
        conn.setConnectTimeout(6000);//连接超时
        //防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

        //得到输入流

        try (InputStream inputStream = conn.getInputStream()) {

            //文件保存位置
            File saveDir = new File(savePath);
            if (!saveDir.exists()) {
                saveDir.mkdirs();
            }
            File file = new File(saveDir + File.separator + fileName);

            FileUtils.copyInputStreamToFile(inputStream, file);

        } catch (Exception e) {

            throw new IOException("文件下载失败", e);
        }

    }


    /**
     * File转为MultipartFile
     *
     * @param filePath
     * @return
     * @throws Exception
     */
    public static MultipartFile file2Multi(String filePath) throws Exception {
        FileItem fileItem = createFileItem(filePath);
        MultipartFile mfile = new CommonsMultipartFile(fileItem);
        return mfile;
    }

    private static FileItem createFileItem(String filePath) {
        File newfile = new File(filePath);

        FileItemFactory factory = new DiskFileItemFactory(16, null);
        String textFieldName = "fileData";
        //int num = filePath.lastIndexOf(".");
        //String extFile = filePath.substring(num);
        FileItem item = factory.createItem(textFieldName, "application/x-zip-compressed", false, newfile.getName());

        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(newfile);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }

    /**
     * 内容写入文件
     *
     * @param content
     * @param toPath
     * @return
     * @throws IOException
     */
    public static File writeToFile(String content, String toPath) throws IOException {
        System.out.println("=============write_json_file:" + toPath);
        //try {
        File file = new File(toPath);
        // 如果文件不存在，则创建
        if (!file.exists()) {
            file.getParentFile().mkdirs();
            file.createNewFile();
        }
        FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(content);
        bw.close();
        System.out.println("完成");
        return file;
/*    	} catch (IOException e) {
    		e.printStackTrace();
    		return false;
    	}*/
    }

    /**
     * 读取文件的内容
     *
     * @param file 想要读取的文件对象
     * @return 返回文件内容
     */
    public static String readTxtString(File file) {
        StringBuilder result = new StringBuilder();
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
            String s = null;
            while ((s = br.readLine()) != null) {//使用readLine方法，一次读一行
                result.append(s);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    /**
     * 检查是否存在队列文件
     *
     * @param id
     * @param baseDir
     * @return
     */
    public static boolean hasQueueConfigFile(String id, String baseDir) {
        String filePath = new StringBuilder(baseDir).append("/").append(id).toString();
        File file = new File(filePath);
        return file.exists();
    }

    /**
     * 写入课件组装队列文件
     *
     * @param id
     * @param config
     * @param baseDir
     * @throws IOException
     */
    public static void saveQueueConfigFile(String id, String config, String baseDir) throws IOException {
        try {
            String filePath = new StringBuilder(baseDir).append("/").append(id).toString();
            writeToFile(config, filePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除队列文件
     *
     * @param id
     * @param baseDir
     */
    public static void delQueueConfigFile(String id, String baseDir) {
        try {
            String filePath = new StringBuilder(baseDir).append("/").append(id).toString();
            File file = new File(filePath);
            if (file.exists() && file.isFile()) {
                file.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取队列文件到Map集合
     *
     * @param baseDir
     * @return
     */
    public static List<Map<String, Object>> getQueueMapList(String baseDir) {
        File dir = new File(baseDir);
        if (dir.exists() && dir.isDirectory()) {
            File[] files = dir.listFiles();
            if (files != null && files.length > 0) {
                List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>(files.length);
                for (File file : files) {
                    String config = readTxtString(file);
                    String id = file.getName();
                    Map<String, Object> map = new HashMap<String, Object>(2);
                    map.put("id", id);
                    map.put("config", config);
                    mapList.add(map);
                }
                return mapList;
            }
        }
        return null;
    }

    //获取课件组装队列文件目录路径
    public static String getQueueConfigFilePath(String tempFileDir) {
        String courseware = "courseware";
        if (!tempFileDir.endsWith("/")) {
            tempFileDir = tempFileDir + "/";
        }
        String ip = IpUtil.getStaticLocalHostIp();
        String dirPath = new StringBuilder(tempFileDir + courseware + "/").append(ip).toString();
        //创建文件夹
        FileUtil.makeDir(dirPath);
        return dirPath;
    }

    //获取课件组装目录路径
    public static String getPackagePath(String tempFileDir) {
        String courseware = "courseware";
        if (!tempFileDir.endsWith("/")) {
            tempFileDir = tempFileDir + "/";
        }
        return tempFileDir + courseware + "/";
    }

    static volatile int j = 0;


    public static boolean checkFile(MultipartFile file, String... suffixs) {
        if (null == file) {
            return false;
        }

        String fileName = file.getOriginalFilename();
        boolean flag = false;
        for (String suffix : suffixs) {
            if (fileName.endsWith(suffix)) {
                flag = true;
            }
        }

        return flag;
    }

    public static Workbook getWorkbook(MultipartFile file) throws IOException {
        String fileName = file.getOriginalFilename();
        Workbook workbook = null;
        if (fileName.endsWith(".xls")) {
            workbook = new HSSFWorkbook(file.getInputStream());
        } else if (fileName.endsWith(".xlsx")) {
            workbook = new XSSFWorkbook(file.getInputStream());
        }
        return workbook;
    }

    /**
     * 清理文件(目录或文件)
     *
     * @param filePath
     */
    public static void deleteFile(String filePath) {
        File file = new File(filePath);
        if (file.isFile() && file.exists()) {
            //清理文件
            file.delete();
        } else if (file.isDirectory()) {
            File[] filelist = file.listFiles();
            if (filelist != null) {
                for (File f : filelist) {
                    deleteFile(f.getAbsolutePath());
                }
                //清理目录
                file.delete();
            }
        }
    }


    public static double readableFileSize(long size, FileType type) {
        if (size <= 0) {
            return 0;
        }

        BigDecimal bg = new BigDecimal(size / Math.pow(1024, type.getCode()));
        double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        return f1;
    }


    public enum FileType {
        B(0, "B"),
        KB(1, "KB"),
        MB(2, "MB"),
        GB(3, "GB"),
        TB(4, "TB");

        private Integer code;
        private String name;

        FileType(Integer code, String name) {
            this.code = code;
            this.name = name;
        }

        public Integer getCode() {
            return code;
        }

        public String getName() {
            return name;
        }


    }

    public static void main(String[] args) throws Exception {
        uploadFile(null, "E://aa/vv/a.txt");
    }
}
